home *** CD-ROM | disk | FTP | other *** search
- /* @(#) $Header: ax25subr.c,v 1.7 91/03/28 19:39:12 deyke Exp $ */
-
- /* Low level AX.25 routines:
- * callsign conversion
- * control block management
- *
- * Copyright 1991 Phil Karn, KA9Q
- */
- #include <stdio.h>
- #include "global.h"
- #include "mbuf.h"
- #include "timer.h"
- #include "ax25.h"
- #include "lapb.h"
- #include <ctype.h>
-
- /*
- * setcall - convert callsign plus substation ID of the form
- * "KA9Q-0" to AX.25 (shifted) address format
- * Address extension bit is left clear
- * Return -1 on error, 0 if OK
- */
- int
- setcall(out,call)
- char *out;
- char *call;
- {
- int csize;
- unsigned ssid;
- register int i;
- register char *dp;
- char c;
-
- if(out == NULLCHAR || call == NULLCHAR || *call == '\0')
- return -1;
-
- /* Find dash, if any, separating callsign from ssid
- * Then compute length of callsign field and make sure
- * it isn't excessive
- */
- dp = strchr(call,'-');
- if(dp == NULLCHAR)
- csize = strlen(call);
- else
- csize = dp - call;
- if(csize > ALEN)
- return -1;
- /* Now find and convert ssid, if any */
- if(dp != NULLCHAR){
- dp++; /* skip dash */
- ssid = atoi(dp);
- if(ssid > 15)
- return -1;
- } else
- ssid = 0;
- /* Copy upper-case callsign, left shifted one bit */
- for(i=0;i<csize;i++){
- c = *call++;
- if(islower(c))
- c = toupper(c);
- *out++ = c << 1;
- }
- /* Pad with shifted spaces if necessary */
- for(;i<ALEN;i++)
- *out++ = ' ' << 1;
-
- /* Insert substation ID field and set reserved bits */
- *out = 0x60 | (ssid << 1);
- return 0;
- }
- int
- addreq(a,b)
- register char *a,*b;
- {
- if (*a++ != *b++) return 0;
- if (*a++ != *b++) return 0;
- if (*a++ != *b++) return 0;
- if (*a++ != *b++) return 0;
- if (*a++ != *b++) return 0;
- if (*a++ != *b++) return 0;
- return (*a & SSID) == (*b & SSID);
- }
- /* Return iface pointer if 'addr' belongs to one of our interfaces,
- * NULLIF otherwise.
- */
- struct iface *
- ismyax25addr(addr)
- char *addr;
- {
- register struct iface *ifp;
-
- for (ifp = Ifaces; ifp; ifp = ifp->next)
- if (ifp->output == ax_output && addreq(ifp->hwaddr, addr))
- break;
- return ifp;
- }
- void
- addrcp(to,from)
- register char *to,*from;
- {
- *to++ = *from++;
- *to++ = *from++;
- *to++ = *from++;
- *to++ = *from++;
- *to++ = *from++;
- *to++ = *from++;
- *to = (*from & SSID) | 0x60;
- }
- /* Convert encoded AX.25 address to printable string */
- char *
- pax25(e,addr)
- char *e;
- char *addr;
- {
- register int i;
- char c;
- char *cp;
-
- cp = e;
- for(i=ALEN;i != 0;i--){
- c = (*addr++ >> 1) & 0x7f;
- if(c != ' ')
- *cp++ = c;
- }
- if((*addr & SSID) != 0)
- sprintf(cp,"-%d",(*addr >> 1) & 0xf); /* ssid */
- else
- *cp = '\0';
- return e;
- }
-
- /* Figure out the frame type from the control field
- * This is done by masking out any sequence numbers and the
- * poll/final bit after determining the general class (I/S/U) of the frame
- */
- int16
- ftype(control)
- register int control;
- {
- if((control & 1) == 0) /* An I-frame is an I-frame... */
- return I;
- if(control & 2) /* U-frames use all except P/F bit for type */
- return (int16)(uchar(control) & ~PF);
- else /* S-frames use low order 4 bits for type */
- return (int16)(uchar(control) & 0xf);
- }
-
-